/*********************************************************************************
Organization 					: 				Georgia Institute of Technology
  
Institute 						:				Cognitive Computing Group(CCL)
 
Authors							: 				Santiago Ontanon, Kinshuk Mishra
 												Neha Sugandh 
 												
Class							:				BuildUnitsGoal
 
Function						: 				Provides a class for holding the build units
****************************************************************************/
package planninglanguage.goals;

import org.jdom.Element;

import planninglanguage.conditions.Condition;
import planninglanguage.conditions.NumberOfUnitsOfTypeCondition;
import planninglanguage.conditions.UnitTypeAtCondition;
import planninglanguage.conditions.UnitTypeExistsCondition;
import planninglanguage.softconditions.AbsoluteNumberOfUnitsOfTypeSoftCondition;
import planninglanguage.softconditions.SoftCondition;
import planninglanguage.softconditions.UnitTypeAtSoftCondition;
import planninglanguage.softconditions.UnitTypeExistsSoftCondition;
import util.XMLWriter;
import base.WargusGameState;

public class AbsoluteBuildUnitsGoal extends Goal implements Cloneable{
	
	String m_unitType = null;
	int m_playerID;
	int m_x = -1;
	int m_y = -1;
	int m_number = 0;
	boolean m_fixedLoc;
	
	public AbsoluteBuildUnitsGoal(String a_unitType,int a_playerID)
	{
		m_unitType = a_unitType;
		m_number = 1;
		m_fixedLoc = false;
		m_playerID = a_playerID;
	}
	
	public Object clone()
	{
		AbsoluteBuildUnitsGoal g = new AbsoluteBuildUnitsGoal(m_unitType,m_playerID);
		g.m_unitType = m_unitType;
		g.m_playerID = m_playerID;
		g.m_x = m_x;
		g.m_y = m_y;
		g.m_number = m_number;
		g.m_fixedLoc = m_fixedLoc;
		
		return g;
	}
	
	public AbsoluteBuildUnitsGoal(String a_unitType,int a_x,int a_y,int a_playerID)
	{
		m_unitType = a_unitType;
		m_x=a_x;
		m_y=a_y;
		m_number = 1;
		m_fixedLoc = true;
		m_playerID = a_playerID;
	}
	
	// for saving & loading
	protected AbsoluteBuildUnitsGoal(String type, int x, int y, int num, 
			int playerID, boolean fixed) {
		m_unitType = type;
		m_x = x;
		m_y = y;
		m_number = num;
		m_playerID = playerID;
		m_fixedLoc = fixed; 
	}

	public AbsoluteBuildUnitsGoal(String a_unitType,int a_num,int a_playerID)
	{
		m_unitType = a_unitType;
		m_number = a_num;
		m_fixedLoc = false;
		m_playerID = a_playerID;
	}

	public Condition generateSuccessCondition(WargusGameState a_gamestate)
	{
		if(m_fixedLoc) {
			return new UnitTypeAtCondition(m_unitType,m_x,m_y,m_playerID);
		} else {
			if (m_number == 1) {
				return new UnitTypeExistsCondition(m_unitType,m_playerID);
			} else {
				return new NumberOfUnitsOfTypeCondition(m_unitType,m_playerID,m_number);
			}
		}
	}
	
	public SoftCondition generateSuccessSoftCondition(WargusGameState a_gamestate)
	{
		if(m_fixedLoc) {
			return new UnitTypeAtSoftCondition(m_unitType,m_x,m_y,m_playerID);
		} else {
			if (m_number == 1) {
				return new UnitTypeExistsSoftCondition(m_unitType,m_playerID);
			} else {
				return new AbsoluteNumberOfUnitsOfTypeSoftCondition(m_unitType,m_playerID,m_number);
			}
		}
	}	
	
	public String toString() {
		return "AbsoluteBuildUnitsGoal( type = " + m_unitType + " number = " + m_number + ")";
	}
	
	public float distance(Goal a_g) {
		if (!(a_g instanceof AbsoluteBuildUnitsGoal)) return 1;

		AbsoluteBuildUnitsGoal g = (AbsoluteBuildUnitsGoal)a_g;
		float du = 1;
		float dn = 1;
		
		if (m_unitType.equals(g.m_unitType)) du = 0;
		if (m_number == g.m_number) dn = 0;
		
		return du*0.25f + dn*0.25f;	/* values are between 0 and 0.5 since at least the goal type is the same */ 
	}	
	
	public void writeXML(XMLWriter w) {
		w.tag(Goal.openTag + " " + Goal.XMLtype + "=\"" + 
				this.getClass().getSimpleName() + "\"");
		{
			w.tag(Goal.XMLplayerID, m_playerID);
			w.tag("type", m_unitType);
			w.tag("number", m_number);			
			w.tag("fixed-location", Boolean.toString(m_fixedLoc));
			w.tag("x", m_x);			
			w.tag("y", m_y);			
		}
		w.tag(Goal.closeTag);
	}
	protected static AbsoluteBuildUnitsGoal loadFromXML(Element e) {
		String type = e.getChildText("type");
		int playerID = Integer.parseInt(e.getChildText(XMLplayerID));
		int number = Integer.parseInt(e.getChildText("number"));
		boolean fixedLoc = Boolean.parseBoolean(e.getChildText("fixed-location"));
		int x = Integer.parseInt(e.getChildText("x"));
		int y = Integer.parseInt(e.getChildText("y"));			
		return new AbsoluteBuildUnitsGoal(type, x, y, number, playerID, fixedLoc);
	}
}
